#include "app_key_ctrl.h"

#include "common_debug.h"
#include "inf_four_way_key.h"

#define ADC_LIST_SW1_IDX 6U /* SW1在ADC-LIST中的索引 */
#define ADC_LIST_SW2_IDX 4U /* SW2在ADC-LIST中的索引 */

/**
 * @brief 四向按键范围映射结构体
 *
 */
typedef struct
{
    key_type_e key_type;    /*!< 按键类型 */
    uint16_t   adc_min_val; /*!< ADC最小值 */
    uint16_t   adc_max_val; /*!< ADC最大值 */
} four_way_key_range_t;

static int32_t  app_key_ctrl_get_adc_value(uint8_t adc_list_idx);
static result_e app_key_ctrl_set_level(void);
// TODO 待实现
static void     app_key_ctrl_up_press(void);
static void     app_key_ctrl_down_press(void);
static void     app_key_ctrl_left_press(void);
static void     app_key_ctrl_right_press(void);
static void     app_key_ctrl_mid_press(void);

/* 四向按键adc映射表 */
static const four_way_key_range_t key_range_map[] = {
    // TODO 待确认adc值范围
    [KEY_TYPE_UP] = { KEY_TYPE_UP, 100, 200 },     [KEY_TYPE_DOWN] = { KEY_TYPE_DOWN, 300, 400 },
    [KEY_TYPE_LEFT] = { KEY_TYPE_LEFT, 500, 600 }, [KEY_TYPE_RIGHT] = { KEY_TYPE_RIGHT, 700, 800 },
    [KEY_TYPE_MID] = { KEY_TYPE_MID, 900, 1000 },
};

static const uint8_t key_range_map_size = sizeof(key_range_map) / sizeof(key_range_map[0]);

extern int32_t adc_real_data_list[];

/**
 * @brief 初始化四向按键
 *
 * @return result_e 初始化结果, 初始化成功返回RESULT_STATUS_OK, 失败返回其他错误码
 */
result_e app_key_ctrl_init(void)
{
    /* 初始化四向按键 */
    CHECK_RESULT(inf_four_way_key_init(), "inf_four_way_key_init failed");

    four_way_key.callbacks[KEY_TYPE_UP]    = app_key_ctrl_up_press;
    four_way_key.callbacks[KEY_TYPE_DOWN]  = app_key_ctrl_down_press;
    four_way_key.callbacks[KEY_TYPE_LEFT]  = app_key_ctrl_left_press;
    four_way_key.callbacks[KEY_TYPE_RIGHT] = app_key_ctrl_right_press;
    four_way_key.callbacks[KEY_TYPE_MID]   = app_key_ctrl_mid_press;

    return RESULT_STATUS_OK;
}

/**
 * @brief 按键处理函数，放在调度器中循环调度5ms
 *
 */
void app_key_ctrl_handle(void)
{
    app_key_ctrl_set_level();

    /* 处理四向按键 */
    inf_four_way_key_handle();
}

static void app_key_ctrl_up_press(void) {}
static void app_key_ctrl_down_press(void) {}
static void app_key_ctrl_left_press(void) {}
static void app_key_ctrl_right_press(void) {}
static void app_key_ctrl_mid_press(void) {}

/**
 * @brief 设置四向按键电平（状态）
 *
 * @return result_e 设置结果, 设置成功返回RESULT_STATUS_OK, 失败返回其他错误码
 */
static result_e app_key_ctrl_set_level(void)
{
    int32_t adc_val1 = app_key_ctrl_get_adc_value(ADC_LIST_SW1_IDX);
    int32_t adc_val2 = app_key_ctrl_get_adc_value(ADC_LIST_SW2_IDX);

    for (uint8_t i = 0; i < key_range_map_size; ++i) {

        const four_way_key_range_t *key_range = &key_range_map[i];
        uint8_t                     level     = FOUR_WAY_KEY_RELEASE_LEVEL;
        int32_t                     adc_val   = 0;

        if (i == KEY_TYPE_MID)
            adc_val = adc_val1;
        else
            adc_val = adc_val2;

        /* 在对应ADC值范围内，设置按键为按下状态, 否则设置为释放状态 */
        if (adc_val >= key_range->adc_min_val && adc_val <= key_range->adc_max_val) {
            level = FOUR_WAY_KEY_PRESS_LEVEL;
        }
        CHECK_RESULT(inf_four_way_key_set_level(key_range->key_type, level),
                     "inf_four_way_key_set_level failed");
    }

    return RESULT_STATUS_OK;
}

/**
 * @brief 获取按键ADC值
 *
 * @return int32_t 按键ADC值
 */
static int32_t app_key_ctrl_get_adc_value(uint8_t adc_list_idx) { return adc_real_data_list[adc_list_idx]; }
